﻿using System;
using System.Collections.Generic;
using System.Text;
using OpenTK;

using OpenTK.Graphics.OpenGL;
using OpenTK;
namespace Xeno.Core
{
    public class XenoMaterial
    {
        /// <summary>
        /// Engine internal.
        /// </summary>
        public enum LightingType
        {
            Directional = 0, Point = 1, Spot = 2
        }
        /// <summary>
        /// Set by the engine, do not concern yourself with it.
        /// </summary>
        public LightingType LightType { get; set; }


        public bool NoLit { get; set; }
        public static Dictionary<string, XenoMaterial> MatMap = new Dictionary<string, XenoMaterial>();
        public string Name { get; set; }
        public XenoTexture DiffuseMap { get; set; }
        public XenoTexture NormalMap { get; set; }
        public XenoTexture HeightMap { get; set; }
        public XenoTexture GlowMap { get; set; }
        public Matrix4 WorldMatrix { get; set; }
        public Matrix4 WorldRotationMatrix { get; set; }
        public Vector4 DiffuseColor { get; set; }
        public Vector4 SpecularColor { get; set; }
        public float SpecularPower { get; set; }
        public enum MaterialFlags
        {
            Lit,X2D,Generic
        }
        public MaterialFlags Flags { get; set; }
        public XenoEffect Effect { get; set; }
        public bool AutoEffectParameters { get; set; }
        public XenoMaterial(string name)
        {
            Name = name;
          
            Flags = MaterialFlags.Lit;
            ResetMaterial();
           
        }
        public XenoMaterial(string name, MaterialFlags flags)
        {
            Name = name;
           
        
            Flags = flags;
            ResetMaterial();
       
        }
        public void ResetMaterial()
        {
            
            DiffuseMap = NormalMap = HeightMap = GlowMap = null;
            Effect = null;
            if (Flags == MaterialFlags.Lit)
            {
                Effect = new XenoEffect("Content/Shader/XenoMaterial_DirLight.vertex", "Content/Shader/XenoMaterial_DirLight.fragment");
            }
            AutoEffectParameters = true;
            
            DiffuseColor = new Vector4(1, 1, 1, 1);
            SpecularColor = new Vector4(1, 1, 1, 1);
            SpecularPower = 0.0f;
            LightType = LightingType.Point;
            NoLit = false;
        }
        /// <summary>
        /// The base XenoEffect class is set up automagically by the engine. Use it wisely, luke.
        /// </summary>
        public void Bind()
        {

            if (DiffuseMap != null) DiffuseMap.Bind(0);
            if (NormalMap != null) NormalMap.Bind(1);
           // GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size((int)XenoCore.DisplayWidth,(int) XenoCore.DisplayHeight));
            XenoCore.CurrentView.Camera.UpdateMatrices();


            if (Effect != null)
            {
                Effect.Use();
            }

            if (AutoEffectParameters && Effect!=null)
            {
                if (XenoCore.CurrentLight != null)
                {
                    
                    Effect.SetVec3("LightDirection", XenoCore.CurrentLight.Light.Direction);
                    Effect.SetVec3("LightPosition", XenoCore.CurrentLight.WorldPosition);
                    Effect.SetColor("LightDiffuseColor", XenoCore.CurrentLight.Light.DiffuseColor);
                    Effect.SetColor("LightAmbientColor", XenoCore.CurrentLight.Light.AmbientColor);
                    Effect.SetFloat("LightRange", XenoCore.CurrentLight.Light.Range);
                }
                int Flag;
                if (NoLit)
                {
                    Flag = 0;
                }
                else
                {
                    Flag = 1;
                }
                Effect.SetInt("MaterialLightingBit", Flag);
                Effect.SetVec2("DisplaySize", new Vector2(XenoCore.DisplayWidth, XenoCore.DisplayHeight));
                Effect.SetFloat("CameraRange", XenoCore.CurrentView.Camera.FarZ);
                Effect.SetVec3("CameraPosition", XenoCore.CurrentView.WorldPosition);
                Effect.SetMat4("NodeWorldMatrix", WorldMatrix, false);
                Effect.SetMat4("NodeRotationMatrix", WorldRotationMatrix, false);
                Effect.SetInt("MaterialLightType", (int)LightType);
                Effect.SetVec4("MaterialDiffuseColor", DiffuseColor);
                Effect.SetVec4("MaterialSpecularColor", SpecularColor);
                Effect.SetFloat("MaterialSpecularPower", SpecularPower);
                Effect.SetVec3("ViewDirection", XenoCore.CurrentView.Direction);
                Effect.SetInt("MaterialDiffuseMap", 0);
                Effect.SetInt("MaterialNormalMap", 1);
                bool dm = false;
                bool nm = false;
                if (DiffuseMap != null)
                {
                    Effect.SetInt("DiffuseMapping", 1);
                }
                else
                {
                    Effect.SetInt("DiffuseMapping", 0);
                }

                if (NormalMap != null)
                {
                    Effect.SetInt("NormalMapping", 1);
                }
                else
                {
                    Effect.SetInt("NormalMapping", 0);
                }
                

                
            }
            
            

        }
        public void Unbind()
        {
     
            if (Effect != null)
            {
                Effect.Fin();
            }
            if (NormalMap != null) NormalMap.Unbind(1);
            if (DiffuseMap != null) DiffuseMap.Unbind(0);


            if (DiffuseMap != null) DiffuseMap.Unbind(0);

        }
    }
}
